module aru (
    input logic                  clk,
    input logic                  rst_n,
    input logic                  ub_wr_rsp_vld,
    input logic                  gm_wr_rsp_vld,
    // Done signal
          is_instr_if.in         u_is_aru_instr_if,
          done_if.out            u_aru_done_if,
    // UB Read data
          aru_ub_rd_req_if.out   u_aru_ub_rd_req_if,
          aru_ub_dat_if.in       u_aru_ub_dat_if,
    // PSB Read data
          psb_rd_req_if.out      u_psb_rd_req_if,
          aru_psb_dat_fp32_if.in u_aru_psb_dat_fp32_if,
    // UB Write request
          aru_ub_wr_req_if.out   u_ub_wr_req_if,
    // GM Write request
          aru_gm_wr_req_if.out   u_gm_wr_req_if
);

    // ARU Instr_Mngr
    aru_ub_rdgen_cfg_if u_aru_ub_rdgen_cfg_if ();
    aru_psb_rdgen_cfg_if u_aru_psb_rdgen_cfg_if ();
    aru_arb_rdgen_cfg_if u_aru_arb_rdgen_cfg_if ();
    aru_mux_cfg_if u_aru_mux_2_to_1_top_cfg_if ();
    aru_mux_cfg_if u_aru_mux_1_to_4_top_cfg_if ();
    aru_mux_cfg_if u_aru_mux_1_to_2_psb_cfg_if ();
    aru_mux_cfg_if u_aru_mux_2_to_1_bottom_cfg_if ();
    aru_mux_cfg_if u_aru_mux_1_to_4_bottom_cfg_if ();
    aru_mux_cfg_if u_aru_mux_1_to_3_unary_cfg_if ();
    aru_add_sub_cfg_if u_aru_add_sub_cfg_if ();
    aru_max_min_cfg_if u_aru_max_min_cfg_if ();
    aru_mul_cfg_if u_aru_mul_cfg_if ();
    aru_div_cfg_if u_aru_div_cfg_if ();
    aru_unary_cfg_if u_aru_neg_cfg_if ();
    aru_unary_cfg_if u_aru_clamp_cfg_if ();
    aru_unary_cfg_if u_aru_exp_cfg_if ();
    aru_unary_cfg_if u_aru_sqrt_cfg_if ();
    aru_unary_cfg_if u_aru_pow_cfg_if ();
    aru_unary_cfg_if u_aru_recp_cfg_if ();
    aru_reduce_cfg_if u_aru_reduce_cfg_if ();
    aru_ub_wrgen_cfg_if u_aru_ub_wrgen_cfg_if ();
    aru_gm_wrgen_cfg_if u_aru_gm_wrgen_cfg_if ();
    aru_arb_wrgen_cfg_if u_aru_arb_wrgen_cfg_if ();
    done_if u_ub_wr_done_if ();
    done_if u_gm_wr_done_if ();
    done_if u_arb_wr_done_if ();

    aru_instr_mngr u_aru_instr_mgr (
        .clk                          (clk),
        .rst_n                        (rst_n),
        .u_is_aru_instr_if            (u_is_aru_instr_if),
        .u_aru_ub_rdgen_cfg_if        (u_aru_ub_rdgen_cfg_if),
        .u_aru_psb_rdgen_cfg_if       (u_aru_psb_rdgen_cfg_if),
        .u_aru_arb_rdgen_cfg_if       (u_aru_arb_rdgen_cfg_if),
        .u_aru_mux_2_to_1_up_cfg_if   (u_aru_mux_2_to_1_top_cfg_if),
        .u_aru_mux_1_to_4_up_cfg_if   (u_aru_mux_1_to_4_top_cfg_if),
        .u_aru_mux_1_to_2_psb_cfg_if  (u_aru_mux_1_to_2_psb_cfg_if),
        .u_aru_mux_2_to_1_down_cfg_if (u_aru_mux_2_to_1_bottom_cfg_if),
        .u_aru_mux_1_to_4_down_cfg_if (u_aru_mux_1_to_4_bottom_cfg_if),
        .u_aru_mux_1_to_3_unary_cfg_if(u_aru_mux_1_to_3_unary_cfg_if),
        .u_aru_add_sub_cfg_if         (u_aru_add_sub_cfg_if),
        .u_aru_max_min_cfg_if         (u_aru_max_min_cfg_if),
        .u_aru_mul_cfg_if             (u_aru_mul_cfg_if),
        .u_aru_div_cfg_if             (u_aru_div_cfg_if),
        .u_aru_neg_cfg_if             (u_aru_neg_cfg_if),
        .u_aru_clamp_cfg_if           (u_aru_clamp_cfg_if),
        .u_aru_exp_cfg_if             (u_aru_exp_cfg_if),
        .u_aru_sqrt_cfg_if            (u_aru_sqrt_cfg_if),
        .u_aru_pow_cfg_if             (u_aru_pow_cfg_if),
        .u_aru_recp_cfg_if            (u_aru_recp_cfg_if),
        .u_aru_reduce_cfg_if          (u_aru_reduce_cfg_if),
        .u_aru_ub_wrgen_cfg_if        (u_aru_ub_wrgen_cfg_if),
        .u_aru_gm_wrgen_cfg_if        (u_aru_gm_wrgen_cfg_if),
        .u_aru_arb_wrgen_cfg_if       (u_aru_arb_wrgen_cfg_if),
        .u_arb_wr_done_if             (u_arb_wr_done_if),
        .u_ub_wr_done_if              (u_ub_wr_done_if),
        .u_gm_wr_done_if              (u_gm_wr_done_if),
        .u_done_if                    (u_aru_done_if)
    );


    // ARU Read modules
    // UB RdGen
    aru_payload_if u_aru_ub_rd_payload_if ();
    aru_ub_rdgen u_aru_ub_rdgen (
        .clk             (clk),
        .rst_n           (rst_n),
        .u_aru_cfg_if    (u_aru_ub_rdgen_cfg_if),
        .u_ub_rd_req_if  (u_aru_ub_rd_req_if),
        .u_aru_ub_dat_if (u_aru_ub_dat_if),
        .u_aru_payload_if(u_aru_ub_rd_payload_if)
    );
    // PSB RdGen
    aru_payload_if u_aru_psb_rd_payload_if ();
    aru_psb_rdgen u_aru_psb_rdgen (
        .clk                  (clk),
        .rst_n                (rst_n),
        .u_aru_cfg_if         (u_aru_psb_rdgen_cfg_if),
        .u_psb_rd_req_if      (u_psb_rd_req_if),
        .u_aru_psb_dat_fp32_if(u_aru_psb_dat_fp32_if),
        .u_aru_payload_if     (u_aru_psb_rd_payload_if)
    );
    // ARB RdGen
    aru_payload_if u_aru_arb_rd_payload_if ();
    arb_rd_req_if u_arb_rd_req_if ();
    aru_arb_dat_if u_aru_arb_dat_if ();
    aru_arb_rdgen u_aru_arb_rdgen (
        .clk             (clk),
        .rst_n           (rst_n),
        .u_arb_rd_req_if (u_arb_rd_req_if),
        .u_aru_arb_dat_if(u_aru_arb_dat_if),
        .u_aru_cfg_if    (u_aru_arb_rdgen_cfg_if),
        .u_aru_payload_if(u_aru_arb_rd_payload_if)
    );

    // ARU MUX modules
    // Mux 1 to 2 PSB
    aru_payload_if u_aru_mux_1_to_2_psb_up_payload_if ();
    aru_payload_if u_aru_mux_1_to_2_psb_down_payload_if ();
    aru_mux_1_to_2 u_aru_mux_1_to_2_psb (
        .clk          (clk),
        .rst_n        (rst_n),
        .u_cfg_if     (u_aru_mux_1_to_2_psb_cfg_if),
        .u_pld_in_if  (u_aru_psb_rd_payload_if),
        .u_pld_out0_if(u_aru_mux_1_to_2_psb_down_payload_if),
        .u_pld_out1_if(u_aru_mux_1_to_2_psb_up_payload_if)
    );
    // Mux 2 to 1 Top
    aru_payload_if u_aru_mux_2_to_1_top_payload_if ();
    aru_mux_2_to_1 u_aru_mux_2_to_1_top (
        .clk         (clk),
        .rst_n       (rst_n),
        .u_cfg_if    (u_aru_mux_2_to_1_top_cfg_if),
        .u_pld_in0_if(u_aru_mux_1_to_2_psb_up_payload_if),
        .u_pld_in1_if(u_aru_ub_rd_payload_if),
        .u_pld_out_if(u_aru_mux_2_to_1_top_payload_if)
    );
    // Mux 2 to 1 Bottom
    aru_payload_if u_aru_mux_2_to_1_bottom_payload_if ();
    aru_mux_2_to_1 u_aru_mux_2_to_1_bottom (
        .clk         (clk),
        .rst_n       (rst_n),
        .u_cfg_if    (u_aru_mux_2_to_1_bottom_cfg_if),
        .u_pld_in0_if(u_aru_arb_rd_payload_if),
        .u_pld_in1_if(u_aru_mux_1_to_2_psb_down_payload_if),
        .u_pld_out_if(u_aru_mux_2_to_1_bottom_payload_if)
    );
    // Mux 1 to 4 Top
    aru_payload_if u_aru_mux_1_to_4_top_payload_max_min_if ();
    aru_payload_if u_aru_mux_1_to_4_top_payload_div_if ();
    aru_payload_if u_aru_mux_1_to_4_top_payload_mul_if ();
    aru_payload_if u_aru_mux_1_to_4_top_payload_add_sub_if ();
    aru_mux_1_to_4 u_aru_mux_1_to_4_top (
        .clk          (clk),
        .rst_n        (rst_n),
        .u_cfg_if     (u_aru_mux_1_to_4_top_cfg_if),
        .u_pld_in_if  (u_aru_mux_2_to_1_top_payload_if),
        .u_pld_out0_if(u_aru_mux_1_to_4_top_payload_add_sub_if),
        .u_pld_out1_if(u_aru_mux_1_to_4_top_payload_mul_if),
        .u_pld_out2_if(u_aru_mux_1_to_4_top_payload_div_if),
        .u_pld_out3_if(u_aru_mux_1_to_4_top_payload_max_min_if)
    );
    // Mux 1 to 4 Bottom
    aru_payload_if u_aru_mux_1_to_4_bottom_payload_max_min_if ();
    aru_payload_if u_aru_mux_1_to_4_bottom_payload_div_if ();
    aru_payload_if u_aru_mux_1_to_4_bottom_payload_mul_if ();
    aru_payload_if u_aru_mux_1_to_4_bottom_payload_add_sub_if ();
    aru_mux_1_to_4 u_aru_mux_1_to_4_bottom (
        .clk          (clk),
        .rst_n        (rst_n),
        .u_cfg_if     (u_aru_mux_1_to_4_bottom_cfg_if),
        .u_pld_in_if  (u_aru_mux_2_to_1_bottom_payload_if),
        .u_pld_out3_if(u_aru_mux_1_to_4_bottom_payload_add_sub_if),
        .u_pld_out2_if(u_aru_mux_1_to_4_bottom_payload_mul_if),
        .u_pld_out1_if(u_aru_mux_1_to_4_bottom_payload_div_if),
        .u_pld_out0_if(u_aru_mux_1_to_4_bottom_payload_max_min_if)
    );

    // ARU Binary modules
    // Add Sub
    aru_payload_if u_aru_add_sub_payload_if ();
    aru_add_sub u_aru_add_sub (
        .clk                (clk),
        .rst_n              (rst_n),
        .u_aru_cfg_if       (u_aru_add_sub_cfg_if),
        .u_aru_pld_top_if   (u_aru_mux_1_to_4_top_payload_add_sub_if),
        .u_aru_pld_bottom_if(u_aru_mux_1_to_4_bottom_payload_add_sub_if),
        .u_aru_pld_left_if  (),
        .u_aru_pld_right_if (u_aru_add_sub_payload_if)
    );
    // Mul
    aru_payload_if u_aru_mul_payload_if ();
    aru_mul u_aru_mul (
        .clk                (clk),
        .rst_n              (rst_n),
        .u_aru_cfg_if       (u_aru_mul_cfg_if),
        .u_aru_pld_top_if   (u_aru_mux_1_to_4_top_payload_mul_if),
        .u_aru_pld_bottom_if(u_aru_mux_1_to_4_bottom_payload_mul_if),
        .u_aru_pld_left_if  (u_aru_add_sub_payload_if),
        .u_aru_pld_right_if (u_aru_mul_payload_if)
    );
    // Div
    aru_payload_if u_aru_div_payload_if ();
    aru_div u_aru_div (
        .clk                (clk),
        .rst_n              (rst_n),
        .u_aru_cfg_if       (u_aru_div_cfg_if),
        .u_aru_pld_top_if   (u_aru_mux_1_to_4_top_payload_div_if),
        .u_aru_pld_bottom_if(u_aru_mux_1_to_4_bottom_payload_div_if),
        .u_aru_pld_left_if  (u_aru_mul_payload_if),
        .u_aru_pld_right_if (u_aru_div_payload_if)
    );
    // Max Min
    aru_payload_if u_aru_max_min_payload_if ();
    aru_max_min u_aru_max_min (
        .clk                (clk),
        .rst_n              (rst_n),
        .u_aru_cfg_if       (u_aru_max_min_cfg_if),
        .u_aru_pld_top_if   (u_aru_mux_1_to_4_top_payload_max_min_if),
        .u_aru_pld_bottom_if(u_aru_mux_1_to_4_bottom_payload_max_min_if),
        .u_aru_pld_left_if  (u_aru_div_payload_if),
        .u_aru_pld_right_if (u_aru_max_min_payload_if)
    );

    // ARU Unary modules
    // Neg
    aru_payload_if u_aru_neg_payload_if ();
    aru_unary u_aru_neg (
        .clk               (clk),
        .rst_n             (rst_n),
        .u_aru_cfg_if      (u_aru_neg_cfg_if),
        .u_aru_pld_left_if (u_aru_max_min_payload_if),
        .u_aru_pld_right_if(u_aru_neg_payload_if)
    );
    // Clamp
    aru_payload_if u_aru_clamp_payload_if ();
    aru_unary u_aru_clamp (
        .clk               (clk),
        .rst_n             (rst_n),
        .u_aru_cfg_if      (u_aru_clamp_cfg_if),
        .u_aru_pld_left_if (u_aru_neg_payload_if),
        .u_aru_pld_right_if(u_aru_clamp_payload_if)
    );
    // Exp
    aru_payload_if u_aru_exp_payload_if ();
    aru_unary u_aru_exp (
        .clk               (clk),
        .rst_n             (rst_n),
        .u_aru_cfg_if      (u_aru_exp_cfg_if),
        .u_aru_pld_left_if (u_aru_clamp_payload_if),
        .u_aru_pld_right_if(u_aru_exp_payload_if)
    );
    // Sqrt
    aru_payload_if u_aru_sqrt_payload_if ();
    aru_unary u_aru_sqrt (
        .clk               (clk),
        .rst_n             (rst_n),
        .u_aru_cfg_if      (u_aru_sqrt_cfg_if),
        .u_aru_pld_left_if (u_aru_exp_payload_if),
        .u_aru_pld_right_if(u_aru_sqrt_payload_if)
    );
    // Pow
    aru_payload_if u_aru_pow_payload_if ();
    aru_unary u_aru_pow (
        .clk               (clk),
        .rst_n             (rst_n),
        .u_aru_cfg_if      (u_aru_pow_cfg_if),
        .u_aru_pld_left_if (u_aru_sqrt_payload_if),
        .u_aru_pld_right_if(u_aru_pow_payload_if)
    );
    // Recp
    aru_payload_if u_aru_recp_payload_if ();
    aru_unary u_aru_recp (
        .clk               (clk),
        .rst_n             (rst_n),
        .u_aru_cfg_if      (u_aru_recp_cfg_if),
        .u_aru_pld_left_if (u_aru_pow_payload_if),
        .u_aru_pld_right_if(u_aru_recp_payload_if)
    );

    // ARU Write modules
    // 1 to 3 Mux Unary
    aru_payload_if u_aru_mux_1_to_3_unary_payload_ub_if ();
    aru_payload_if u_aru_mux_1_to_3_unary_payload_gm_if ();
    aru_payload_if u_aru_mux_1_to_3_unary_payload_arb_if ();
    aru_mux_1_to_3 u_aru_mux_1_to_3_unary (
        .clk          (clk),
        .rst_n        (rst_n),
        .u_cfg_if     (u_aru_mux_1_to_3_unary_cfg_if),
        .u_pld_in_if  (u_aru_recp_payload_if),
        .u_pld_out0_if(u_aru_mux_1_to_3_unary_payload_arb_if),
        .u_pld_out1_if(u_aru_mux_1_to_3_unary_payload_gm_if),
        .u_pld_out2_if(u_aru_mux_1_to_3_unary_payload_ub_if)
    );
    // UB WrGen
    aru_ub_wrgen u_aru_ub_wrgen (
        .clk           (clk),
        .rst_n         (rst_n),
        .ub_wr_rsp_vld (ub_wr_rsp_vld),
        .u_aru_cfg_if  (u_aru_ub_wrgen_cfg_if),
        .u_aru_pld_if  (u_aru_mux_1_to_3_unary_payload_ub_if),
        .u_ub_wr_req_if(u_ub_wr_req_if),
        .u_done_if     (u_ub_wr_done_if)
    );
    // GM WrGen
    aru_gm_wrgen u_aru_gm_wrgen (
        .clk           (clk),
        .rst_n         (rst_n),
        .gm_wr_rsp_vld (gm_wr_rsp_vld),
        .u_aru_cfg_if  (u_aru_gm_wrgen_cfg_if),
        .u_aru_pld_if  (u_aru_mux_1_to_3_unary_payload_gm_if),
        .u_gm_wr_req_if(u_gm_wr_req_if),
        .u_done_if     (u_gm_wr_done_if)
    );

    // Reduce
    aru_payload_if u_aru_reduce_pld_if ();
    aru_reduce u_aru_reduce (
        .clk                (clk),
        .rst_n              (rst_n),
        .u_aru_cfg_if       (u_aru_reduce_cfg_if),
        .u_aru_payload_if   (u_aru_mux_1_to_3_unary_payload_arb_if),
        .u_aru_reduce_pld_if(u_aru_reduce_pld_if)
    );

    // ARB WrGen
    arb_wr_req_if u_arb_wr_req_if ();
    aru_arb_wrgen u_aru_arb_wrgen (
        .clk            (clk),
        .rst_n          (rst_n),
        .u_aru_cfg_if   (u_aru_arb_wrgen_cfg_if),
        .u_aru_pld_if   (u_aru_reduce_pld_if),
        .u_arb_wr_req_if(u_arb_wr_req_if),
        .u_done_if      (u_arb_wr_done_if)
    );

    // ARB Module
    aru_arb u_aru_arb (
        .clk             (clk),
        .rst_n           (rst_n),
        .u_arb_wr_req_if (u_arb_wr_req_if),
        .u_arb_rd_req_if (u_arb_rd_req_if),
        .u_aru_arb_dat_if(u_aru_arb_dat_if)
    );

endmodule
